package api

import (
	"net/http"
	"time"

	"game-handker/pkg/jwt"
	"game-handker/pkg/redis"
	"game-handker/pkg/sms"

	"github.com/gin-gonic/gin"
)

func SendCodeHandler(smsClient sms.Client, redisClient *redis.RedisClient) gin.HandlerFunc {
	return func(c *gin.Context) {
		phoneNumber := c.Query("phone")
		code := sms.GenerateRandomCode(6)

		err := smsClient.Send(phoneNumber, code)
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to send code"})
			return
		}

		err = redisClient.SetCode(phoneNumber, code)
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to store code"})
			return
		}

		c.JSON(http.StatusOK, gin.H{"message": "code sent successfully"})
	}
}

func ValidateCodeHandler(redisClient *redis.RedisClient) gin.HandlerFunc {
	return func(c *gin.Context) {
		phoneNumber := c.Query("phone")
		inputCode := c.Query("code")

		storedCode, err := redisClient.GetCode(phoneNumber)
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to get code"})
			return
		}

		if storedCode != inputCode {
			c.JSON(http.StatusBadRequest, gin.H{"error": "invalid code"})
			return
		}
		token, err := jwt.GenerateToken(phoneNumber)
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to generate token"})
			return
		}

		c.JSON(http.StatusOK, gin.H{"message": "code is valid", "token": token})
	}
}

func RenewTokenHandler() gin.HandlerFunc {
	return func(c *gin.Context) {
		tokenString := c.GetHeader("Authorization")
		if tokenString == "" {
			c.JSON(http.StatusBadRequest, gin.H{"error": "missing token"})
			return
		}

		claims, err := jwt.ParseToken(tokenString)
		if err != nil {
			c.JSON(http.StatusUnauthorized, gin.H{"error": "invalid token"})
			return
		}
		if time.Unix(claims.ExpiresAt, 0).Sub(time.Now()) < 1*time.Hour {
			// 生成新的 Token
			newToken, err := jwt.GenerateToken(claims.UserName)
			if err != nil {
				c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to renew token"})
				return
			}

			c.JSON(http.StatusOK, gin.H{"message": "token renewed", "token": newToken})
		} else {
			c.JSON(http.StatusOK, gin.H{"message": "token is still valid"})
		}
	}
}
